"""
Case Type   : 资源池化
Case Name   : 扩容过程中，原主节点注入cma故障
Create At   : 2024.10
Owner       : chen
Description :
    1.执行扩容
    gs_expansion -U {user} -G {user} -X {xml} -h {ip}
    2.扩容中，原主节点注入cms故障
    cd $GAUSSHOME/bin
    mv cm_agent cm_agent_1
    kill -9 pid(cm_agent)
    3.1恢复主节点故障
    cd $GAUSSHOME/bin
    mv cm_agent_1 cm_agent
    cm_ctl start -n 1
    cm_ctl switchover -a
    3.2重新执行扩容
    gs_expansion -U {user} -G {user} -X {xml} -h {ip}
    4.检查扩容情况
    cm_ctl -query -Cv
    查看各节点pg_hba.conf配置文件有无新节点信息
    5.检查数据一致性
    主库：drop table if exists test_table;
    create table test_table(id int, name varchar);
    insert into test_table values(1,'zs')(2, 'ls');
    备库：select * from test_table;
    6.恢复环境
    执行缩容；
    恢复集群状态：cm_ctl switchover -a
Expect      :
    1.工具扩容正常
    2.注入故障成功
    3.成功
    4.检查正常
    5.校验正常
    6.恢复环境
"""

import os
import unittest
import time
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.ComThread import ComThread
from yat.test import Node
from yat.test import macro

class SharedStorage(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_node = Node('PrimaryDbUser')
        self.pri_root_node = Node('PrimaryRoot')
        self.pri_comsh = CommonSH('PrimaryDbUser')
        self.pri_rootsh = CommonSH('PrimaryRoot')
        self.sta2_comsh = CommonSH('Standby2DbUser')
        self.sta2_node = Node('Standby2DbUser')
        self.com = Common()
        self.constant = Constant()
        self.db_host = Node('Standby2DbUser').db_host
        self.s_user = self.pri_node.ssh_user

    def test_shared_storage(self):
        text = '-----step1: 执行扩容 expect: 工具扩容正常-----'
        self.log.info(text)
        xml_path = macro.DB_XML_PATH
        course = ComThread(self.pri_rootsh.exec_expension, 
            args=(self.s_user, self.s_user, self.db_host, xml_path, '',))
        course.setDaemon(True)
        course.start()
        time.sleep(2)

        text = '-----step2: 扩容中，原主节点注入cma故障 expect: 注入故障成功-----'
        self.log.info(text)
        pid = self.com.get_pid(self.pri_node, 'bin/cm_agent')
        cmd = f'''source {macro.DB_ENV_PATH}; \
            cd $GAUSSHOME/bin; \
            mv cm_agent cm_agent_bak'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        cmd = f'''kill -9 {pid}'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        time.sleep(5)
        course.join()
        expansion_result = course.get_result()
        self.assertFalse(expansion_result)

        text = '-----step3.1: 恢复主节点故障 expect: 成功-----'
        self.log.info(text)
        cmd = f'''source {macro.DB_ENV_PATH}; \
            cd $GAUSSHOME/bin; \
            mv cm_agent_bak cm_agent'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        res = self.pri_comsh.exec_cm_ctl('start', '-n 1')
        self.log.info(res)
        self.assertIn(self.constant.cm_start_node_success_msg, res)
        res = self.pri_comsh.exec_cm_ctl('switchover', '-a')
        self.log.info(res)
        self.assertIn(self.constant.cm_switchover_success_msg, res)

        text = f'-----step3.2: 重新执行扩容 expect: 成功-----'
        self.log.info(text)
        xml_path = macro.DB_XML_PATH
        cmd = f'''gs_expansion -U {self.s_user} -G \
            {self.s_user} -X {xml_path} -h {self.db_host}'''
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            expect <<EOF
            set timeout 300
            spawn {cmd}
            expect "*assword*:"
            send "{self.pri_root_node.ssh_password}\\n"
            expect "*assword*:"
            send "{self.pri_root_node.ssh_password}\\n"
            expect "*lease repeat for database*:"
            send "{macro.GAUSSDB_INIT_USER_PASSWD}\\n"
            expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd)
        res = self.pri_root_node.sh(execute_cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.db_host}:\tSuccess', res)

        text = "-----step4: 检查扩容情况 expect: 成功-----"
        self.log.info(text)
        res = self.pri_comsh.exec_cm_ctl('query', '-Cv')
        self.log.info(res)
        node_arr = res.splitlines()[-1].split('|')
        for node_mes in node_arr:
            self.assertIn('Normal', node_mes)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/postgresql.conf | grep {self.db_host}'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.db_host}', res)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/postgresql.conf | grep {self.pri_node.db_host}'''
        self.log.info(cmd)
        res = self.sta2_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.pri_node.db_host}', res)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/pg_hba.conf | grep {self.db_host}'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.db_host}', res)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/pg_hba.conf | grep {self.pri_node.db_host}'''
        self.log.info(cmd)
        res = self.sta2_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.pri_node.db_host}', res)

        text = "-----step5: 检查数据一致性 expect: 成功-----"
        self.log.info(text)
        res = self.pri_comsh.execut_db_sql(f'''drop table if exists test_table;
            create table test_table(id int, name varchar);
            insert into test_table values(1,'zs'),(2, 'ls');''')
        self.log.info(res)
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, res,
                      '执行失败' + text)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, res,
                      '执行失败' + text)
        self.assertIn(self.constant.INSERT_SUCCESS_MSG, res,
                      '执行失败' + text)
        res = self.sta2_comsh.execut_db_sql(f'''select * from test_table;''')
        self.log.info(res)
        self.assertIn('(2 rows)', res, '执行失败' + text)

    def tearDown(self):
        text = "-----step6: 恢复环境 expect: 成功-----"
        self.log.info(text)
        cmd = f'''source {macro.DB_ENV_PATH};
            expect <<EOF
            set timeout 600
            spawn gs_dropnode -U {self.s_user} -G {self.s_user} \
            -h {self.db_host}
            expect "*drop the target node (yes/no)?*"
            send "yes\\n"
            expect eof\n''' + '''EOF'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn('Success to drop the target nodes', res)
        res = self.sta2_node.sh(f'source {macro.DB_ENV_PATH}; ' \
            'gs_uninstall --delete-data').result()
        self.log.info(res)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')